package com.woniu.comment.util;



import com.woniu.model.Coordinate;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Component
public class LocationUtils {

    /**
     * 计算两个坐标的直线距离，单位米
     * @param longitude1 坐标1经度
     * @param latitude1  坐标1纬度
     * @param longitude2 坐标2经度
     * @param latitude2  坐标2纬度
     * @return
     */
    public static double calcDistance(double longitude1, double latitude1, double longitude2, double latitude2) {
        GlobalCoordinates source = new GlobalCoordinates(latitude1, longitude1);
        GlobalCoordinates target = new GlobalCoordinates(latitude2, longitude2);

        GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(Ellipsoid.Sphere, source, target);
        return geoCurve.getEllipsoidalDistance();
    }

    /**
     * 判断是否有其他坐标在指定距离范围内
     * @param targetLongitude 目标点的经度
     * @param targetLatitude 目标点的纬度
     * @param coordinates 其他坐标点的列表
     * @param distanceInMeters 指定的距离范围，单位为米
     * @return 如果存在其他坐标点在指定距离范围内，则返回true；否则返回false
     */
    public static boolean hasAnotherStation(double targetLongitude, double targetLatitude,
                                            List<Coordinate> coordinates, double distanceInMeters) {
        for (Coordinate coord : coordinates) {
            double distance = calcDistance(targetLongitude, targetLatitude, coord.getLongitude(), coord.getLatitude());
            if (distance <= distanceInMeters) {
                return true;
            }
        }
        return false;
    }


    /**
     * 使用示例
     */
    public static void main(String[] args) {
        double targetLongitude = 180.0; // 给定的目标经度
        double targetLatitude = 20.0; // 给定的目标纬度
        double distanceInMeters = 5000.0; // 指定的距离范围，单位为米
        List<Coordinate> allCoordinates = new ArrayList<>(Arrays.asList(
                new Coordinate(120.1, 30.1),
                new Coordinate(120.2, 30.2),
                new Coordinate(120.3, 30.3)
        ));

        boolean hasNearbyCoordinates = hasAnotherStation(targetLongitude, targetLatitude, allCoordinates, distanceInMeters);

        if (hasNearbyCoordinates) {
            System.out.println("目标附近" + distanceInMeters + "米内有其他坐标点。");
        } else {
            System.out.println("目标附近" + distanceInMeters + "米内没有其他坐标点。");
        }
    }

    /**
     * 在坐标集合中找到与指定坐标最近的坐标
     * @param targetLongitude 目标坐标的经度
     * @param targetLatitude 目标坐标的纬度
     * @param coordinates 传入的坐标集合
     * @return 与指定坐标最近的坐标
     */
    public static Coordinate findNearestCoordinate(double targetLongitude, double targetLatitude, List<Coordinate> coordinates) {
        if (coordinates == null || coordinates.isEmpty()) {
            return null;
        }

        Coordinate nearestCoordinate = null;
        double nearestDistance = Double.MAX_VALUE;

        for (Coordinate coord : coordinates) {
            double distance = calcDistance(targetLongitude, targetLatitude, coord.getLongitude(), coord.getLatitude());
            if (distance < nearestDistance) {
                nearestDistance = distance;
                nearestCoordinate = coord;
            }
        }

        return nearestCoordinate;
    }
}